package com.lyl.serviceacl.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.lyl.serviceacl.entity.Permission;
import com.lyl.serviceacl.entity.RolePermission;
import com.lyl.serviceacl.entity.User;
import com.lyl.serviceacl.helper.MemuHelper;
import com.lyl.serviceacl.mapper.PermissionMapper;
import com.lyl.serviceacl.service.PermissionService;
import com.lyl.serviceacl.service.RolePermissionService;
import com.lyl.serviceacl.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2020-01-12
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private RolePermissionService rolePermissionService;
    
    @Autowired
    private UserService userService;
    
    //获取全部菜单
    @Override
    public List<Permission> queryAllMenu() {

        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<Permission> permissionList = baseMapper.selectList(wrapper);

        List<Permission> result = bulidPermission(permissionList);

        return result;
    }

    //根据角色获取菜单
    @Override
    public List<Permission> selectAllMenu(Long roleId) {
//        List<Permission> allPermissionList = baseMapper.selectList(new QueryWrapper<Permission>().orderByAsc("CAST(id AS SIGNED)"));
       // 获取所有权限
        List<Permission> allPermissionList = baseMapper.selectList(new QueryWrapper<Permission>().orderByAsc("id"));

        //根据角色id获取角色权限
        List<RolePermission> rolePermissionList = rolePermissionService.list(new QueryWrapper<RolePermission>().eq("role_id",roleId));
        //转换给角色id与角色权限对应Map对象
        List<Long> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());

        allPermissionList.forEach(permission -> {
            if(permissionIdList.contains(permission.getId())) {
                permission.setSelect(true);
            } else {
                permission.setSelect(false);
            }
        });
        // 权限树化



        List<Permission> permissionList = bulidPermission(allPermissionList);
        return permissionList;
    }

    //给角色分配权限
    @Override
    public void saveRolePermissionRealtionShip(Long roleId, Long[] permissionIds) {

        rolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", roleId));

  

        List<RolePermission> rolePermissionList = new ArrayList<>();
        for(Long permissionId : permissionIds) {
            if(StringUtils.isEmpty(permissionId)) continue;
      
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionList.add(rolePermission);
        }
        rolePermissionService.saveBatch(rolePermissionList);
    }

    //递归删除菜单
    @Override
    public void removeChildById(Long id) {
        List<Long> idList = new ArrayList<>();
        this.selectChildListById(id, idList);

        idList.add(id);
        baseMapper.deleteBatchIds(idList);
    }

    //根据用户id获取用户菜单, 路由菜单
    @Override
    public List<String> selectPermissionValueByUserId(Long id) {

        List<String> selectPermissionValueList = null;
        if(this.isSysAdmin(id)) {
            //如果是系统管理员，获取所有权限
            selectPermissionValueList = baseMapper.selectAllPermissionValue();
        } else {
            selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
        }
        return selectPermissionValueList;
    }

    // 获取路由菜单
    @Override
    public List<JSONObject> selectPermissionByUserId(Long userId) {
        List<Permission> selectPermissionList = null;
        List<Permission> permissionList =null;
        if(this.isSysAdmin(userId)) {
            //如果是超级管理员，获取所有菜单
            selectPermissionList = baseMapper.selectList(null);
            permissionList= bulidPermission(selectPermissionList);
            List<JSONObject> result = MemuHelper.bulid(permissionList);
            return result;
        } else {
            selectPermissionList = baseMapper.selectPermissionByUserId(userId);
            permissionList= bulidPermissionNomal(selectPermissionList);

            List<JSONObject> result = MemuHelper.bulidMyMenu(permissionList);
            return result;
        }






    }

    /**
     * 判断用户是否系统管理员
     * @param userId
     * @return
     */
    private boolean isSysAdmin(Long userId) {
        User user = userService.getById(userId);

        if(null != user && "admin".equals(user.getUsername())) {
            return true;
        }
        return false;
    }

    /**
     *	递归获取子节点
     * @param id
     * @param idList
     */
    private void selectChildListById(Long id, List<Long> idList) {
        List<Permission> childList = baseMapper.selectList(new QueryWrapper<Permission>().eq("pid", id).select("id"));
        childList.stream().forEach(item -> {
            idList.add(item.getId());
            this.selectChildListById(item.getId(), idList);
        });
    }




    //========================递归查询所有菜单================================================
    //获取全部菜单
    @Override
    public List<Permission> queryAllMenuZxjy() {
        //1 查询菜单表所有数据
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");

        // 查询所有的 菜单
        List<Permission> permissionList = baseMapper.selectList(wrapper);


        //2 把查询所有菜单list集合按照要求进行封装  树化
        List<Permission> resultList = bulidPermission(permissionList);
        return resultList;
    }

    public static List<Permission> bulidPermissionNomal(List<Permission> permissionList) {

        //创建list集合，用于数据最终封装
        List<Permission> finalNode = new ArrayList<>();
        //把所有菜单list集合遍历，得到顶层菜单 pid=0菜单，设置level是1
        for(Permission permissionNode : permissionList) {
            //得到顶层菜单 pid=0菜单
            if("1".equals(permissionNode.getPid().toString())) {
                //设置顶层菜单的level是1
                permissionNode.setLevel(1);
                finalNode.add(permissionNode);// 添加一级菜单
                selectChildren(permissionNode,permissionList);

                //根据顶层菜单，向里面进行查询子菜单，封装到finalNode里面
//                finalNode.add(selectChildren(permissionNode,permissionList));
            }
        }
        return finalNode;
    }

    //把返回所有菜单list集合进行封装的方法
    public static List<Permission> bulidPermission(List<Permission> permissionList) {

        //创建list集合，用于数据最终封装
        List<Permission> finalNode = new ArrayList<>();
        //把所有菜单list集合遍历，得到顶层菜单 pid=0菜单，设置level是1
        for(Permission permissionNode : permissionList) {
            //得到顶层菜单 pid=0菜单
            if("0".equals(permissionNode.getPid().toString())) {
                //设置顶层菜单的level是1
                permissionNode.setLevel(1);
                // 每一个菜单都有可能有自己的 子菜单
                selectChildren(permissionNode,permissionList);

                finalNode.add(permissionNode);// 添加一级菜单
                //根据顶层菜单，向里面进行查询子菜单，封装到finalNode里面
//                finalNode.add(selectChildren(permissionNode,permissionList));
            }
        }
        return finalNode;
    }

    private static void selectChildren(Permission parentNode, List<Permission> allPermission
    ) {
        for (Permission p:allPermission    ) {
            if(p.getPid().equals(parentNode.getId())){

                p.setLevel(parentNode.getLevel()+1);//

                parentNode.getChildren().add(p);
                // 子孩子再找自己的子孩子
                selectChildren(p,allPermission);
            }
        }
    }


    //============递归删除菜单==================================
    @Override
    public void removeChildByIdZxjy(Long id) {
        //1 创建list集合，用于封装所有删除菜单id值
        List<Long> idList = new ArrayList<>();
        //2 向idList集合设置删除菜单id
        this.selectPermissionChildById(id,idList);
        //把当前id封装到list里面
        idList.add(id);
        baseMapper.deleteBatchIds(idList);
    }

    //2 根据当前菜单id，查询菜单里面子菜单id，封装到list集合
    private void selectPermissionChildById(Long id, List<Long> idList) {
        //查询菜单里面子菜单id
        QueryWrapper<Permission>  wrapper = new QueryWrapper<>();
        wrapper.eq("pid",id);
        wrapper.select("id");
        List<Permission> childIdList = baseMapper.selectList(wrapper);
        //把childIdList里面菜单id值获取出来，封装idList里面，做递归查询
        childIdList.stream().forEach(item -> {
            //封装idList里面
            idList.add(item.getId());
            //递归查询
            this.selectPermissionChildById(item.getId(),idList);
        });
    }

    //=========================给角色分配菜单=======================
    @Override
    public void saveRolePermissionRealtionShipZxjy(Long roleId, Long[] permissionIds) {
        QueryWrapper<RolePermission> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("role_id",roleId);
        rolePermissionService.remove(queryWrapper);
        //roleId角色id
        //permissionId菜单id 数组形式
        //1 创建list集合，用于封装添加数据
        List<RolePermission> rolePermissionList = new ArrayList<>();
        //遍历所有菜单数组
        for(Long perId : permissionIds) {
            //RolePermission对象
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(perId);
            //封装到list集合
            rolePermissionList.add(rolePermission);
        }
        //添加到角色菜单关系表
        rolePermissionService.saveBatch(rolePermissionList);
    }
}
